#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QFormLayout>
#include <QAction>
#include <QMenu>
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>
#include <QThread>
#include <QStandardPaths>
#include <QDir>
#include <QApplication>
#include <QSplitter>
#include <QGroupBox>
#include <QHeaderView>
#include <QDebug>

#include <zip.h>
#include <QFileInfo>
#include <QDirIterator>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_centralWidget(nullptr)
    , m_mainSplitter(nullptr)
    , m_configGroup(nullptr)
    , m_nameEdit(nullptr)
    , m_versionEdit(nullptr)
    , m_descriptionEdit(nullptr)
    , m_outputEdit(nullptr)
    , m_outputDirEdit(nullptr)
    , m_sourceDirEdit(nullptr)
    , m_filesGroup(nullptr)
    , m_filesList(nullptr)
    , m_foldersList(nullptr)
    , m_addFilesBtn(nullptr)
    , m_addFoldersBtn(nullptr)
    , m_removeBtn(nullptr)
    , m_packBtn(nullptr)
    , m_progressBar(nullptr)
    , m_statusLabel(nullptr)
    , m_configModified(false)
    , m_packWorker(nullptr)
{
    setWindowTitle("Pack Tools - 文件打包工具");
    setMinimumSize(800, 600);
    resize(1000, 700);
    
    // 加载设置
    loadSettings();
    
    // 初始化PackWorker（先不创建线程）
    m_packWorker = nullptr;
    m_workerThread = nullptr;
    
    setupUI();
    setupMenuBar();
    connectSignals();
    updateUI();
    
    // 创建默认配置
    newConfig();
}

MainWindow::~MainWindow()
{
    // 清理工作线程
    if (m_workerThread && m_workerThread->isRunning()) {
        if (m_packWorker) {
            m_packWorker->cancelPacking();
        }
        m_workerThread->quit();
        m_workerThread->wait(3000); // 等待3秒
        if (m_workerThread->isRunning()) {
            m_workerThread->terminate();
            m_workerThread->wait(1000);
        }
    }
    
    // 保存设置
    saveSettings();
}

void MainWindow::setupUI()
{
    m_centralWidget = new QWidget(this);
    setCentralWidget(m_centralWidget);
    
    // 创建主分割器
    m_mainSplitter = new QSplitter(Qt::Horizontal, this);
    
    // 左侧：配置编辑区域
    setupConfigArea();
    
    // 右侧：文件和文件夹列表
    setupFilesArea();
    
    // 底部：按钮和进度条
    setupBottomArea();
    
    // 主布局
    QVBoxLayout* mainLayout = new QVBoxLayout(m_centralWidget);
    mainLayout->addWidget(m_mainSplitter);
    mainLayout->addLayout(setupBottomLayout());
    
    // 设置分割器比例
    m_mainSplitter->setSizes({400, 500});
}

void MainWindow::setupConfigArea()
{
    m_configGroup = new QGroupBox("配置信息", this);
    
    QFormLayout* configLayout = new QFormLayout(m_configGroup);
    
    m_nameEdit = new QLineEdit();
    m_versionEdit = new QLineEdit();
    m_descriptionEdit = new QLineEdit();
    m_outputEdit = new QLineEdit();
    
    // 输出目录选择
    QHBoxLayout* outputDirLayout = new QHBoxLayout();
    m_outputDirEdit = new QLineEdit();
    QPushButton* outputDirBtn = new QPushButton("选择");
    outputDirBtn->setFixedWidth(60);
    outputDirLayout->addWidget(m_outputDirEdit);
    outputDirLayout->addWidget(outputDirBtn);
    connect(outputDirBtn, &QPushButton::clicked, this, &MainWindow::selectOutputDir);
    
    // 源目录选择
    QHBoxLayout* sourceDirLayout = new QHBoxLayout();
    m_sourceDirEdit = new QLineEdit();
    QPushButton* sourceDirBtn = new QPushButton("选择");
    sourceDirBtn->setFixedWidth(60);
    sourceDirLayout->addWidget(m_sourceDirEdit);
    sourceDirLayout->addWidget(sourceDirBtn);
    connect(sourceDirBtn, &QPushButton::clicked, this, &MainWindow::selectSourceDir);
    
    configLayout->addRow("名称:", m_nameEdit);
    configLayout->addRow("版本:", m_versionEdit);
    configLayout->addRow("描述:", m_descriptionEdit);
    configLayout->addRow("输出文件:", m_outputEdit);
    configLayout->addRow("输出目录:", outputDirLayout);
    configLayout->addRow("源目录:", sourceDirLayout);
    
    m_mainSplitter->addWidget(m_configGroup);
}

void MainWindow::setupFilesArea()
{
    m_filesGroup = new QGroupBox("文件和文件夹", this);
    
    QVBoxLayout* filesLayout = new QVBoxLayout(m_filesGroup);
    
    // 文件列表
    QLabel* filesLabel = new QLabel("文件列表:");
    m_filesList = new QListWidget();
    m_filesList->setSelectionMode(QAbstractItemView::ExtendedSelection);
    
    // 文件夹列表
    QLabel* foldersLabel = new QLabel("文件夹列表:");
    m_foldersList = new QListWidget();
    m_foldersList->setSelectionMode(QAbstractItemView::ExtendedSelection);
    
    // 按钮
    QHBoxLayout* buttonsLayout = new QHBoxLayout();
    m_addFilesBtn = new QPushButton("添加文件");
    m_addFoldersBtn = new QPushButton("添加文件夹");
    m_removeBtn = new QPushButton("删除选中");
    
    buttonsLayout->addWidget(m_addFilesBtn);
    buttonsLayout->addWidget(m_addFoldersBtn);
    buttonsLayout->addWidget(m_removeBtn);
    buttonsLayout->addStretch();
    
    filesLayout->addWidget(filesLabel);
    filesLayout->addWidget(m_filesList);
    filesLayout->addWidget(foldersLabel);
    filesLayout->addWidget(m_foldersList);
    filesLayout->addLayout(buttonsLayout);
    
    m_mainSplitter->addWidget(m_filesGroup);
}

QHBoxLayout* MainWindow::setupBottomLayout()
{
    QHBoxLayout* bottomLayout = new QHBoxLayout();
    
    m_packBtn = new QPushButton("开始打包");
    m_packBtn->setMinimumHeight(35);
    
    m_progressBar = new QProgressBar();
    m_progressBar->setVisible(false);
    
    m_statusLabel = new QLabel("就绪");
    
    bottomLayout->addWidget(m_statusLabel);
    bottomLayout->addStretch();
    bottomLayout->addWidget(m_progressBar);
    bottomLayout->addWidget(m_packBtn);
    
    return bottomLayout;
}

void MainWindow::setupBottomArea()
{
    // 创建状态栏
    statusBar()->showMessage("就绪");
}

void MainWindow::setupMenuBar()
{
    QMenuBar* menuBar = this->menuBar();
    
    // 文件菜单
    QMenu* fileMenu = menuBar->addMenu("文件(&F)");
    
    QAction* newAction = new QAction("新建配置(&N)", this);
    newAction->setShortcut(QKeySequence::New);
    connect(newAction, &QAction::triggered, this, &MainWindow::newConfig);
    fileMenu->addAction(newAction);
    
    QAction* openAction = new QAction("打开配置(&O)", this);
    openAction->setShortcut(QKeySequence::Open);
    connect(openAction, &QAction::triggered, this, &MainWindow::openConfig);
    fileMenu->addAction(openAction);
    
    fileMenu->addSeparator();
    
    QAction* saveAction = new QAction("保存配置(&S)", this);
    saveAction->setShortcut(QKeySequence::Save);
    connect(saveAction, &QAction::triggered, this, &MainWindow::saveConfig);
    fileMenu->addAction(saveAction);
    
    QAction* saveAsAction = new QAction("另存为(&A)", this);
    saveAsAction->setShortcut(QKeySequence::SaveAs);
    connect(saveAsAction, &QAction::triggered, this, &MainWindow::saveAsConfig);
    fileMenu->addAction(saveAsAction);
    
    fileMenu->addSeparator();
    
    QAction* exitAction = new QAction("退出(&X)", this);
    exitAction->setShortcut(QKeySequence::Quit);
    connect(exitAction, &QAction::triggered, this, &QWidget::close);
    fileMenu->addAction(exitAction);
    
    // 帮助菜单
    QMenu* helpMenu = menuBar->addMenu("帮助(&H)");
    QAction* aboutAction = new QAction("关于(&A)", this);
    connect(aboutAction, &QAction::triggered, [this]() {
        QMessageBox::about(this, "关于", "Pack Tools v1.0.0\n\n文件打包工具\n基于Qt开发");
    });
    helpMenu->addAction(aboutAction);
}

void MainWindow::connectSignals()
{
    // 配置变化信号
    connect(m_nameEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    connect(m_versionEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    connect(m_descriptionEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    connect(m_outputEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    connect(m_outputDirEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    connect(m_sourceDirEdit, &QLineEdit::textChanged, this, &MainWindow::onConfigChanged);
    
    // 路径验证信号
    connect(m_outputDirEdit, &QLineEdit::textChanged, this, &MainWindow::validatePaths);
    connect(m_sourceDirEdit, &QLineEdit::textChanged, this, &MainWindow::validatePaths);
    
    // 按钮信号
    connect(m_addFilesBtn, &QPushButton::clicked, this, &MainWindow::addFiles);
    connect(m_addFoldersBtn, &QPushButton::clicked, this, &MainWindow::addFolders);
    connect(m_removeBtn, &QPushButton::clicked, this, &MainWindow::removeSelectedItems);
    connect(m_packBtn, &QPushButton::clicked, this, &MainWindow::startPacking);
}

void MainWindow::updateUI()
{
    // 临时断开配置变化信号，避免循环调用
    m_nameEdit->blockSignals(true);
    m_versionEdit->blockSignals(true);
    m_descriptionEdit->blockSignals(true);
    m_outputEdit->blockSignals(true);
    m_outputDirEdit->blockSignals(true);
    m_sourceDirEdit->blockSignals(true);
    
    // 更新配置字段
    m_nameEdit->setText(m_config.name);
    m_versionEdit->setText(m_config.version);
    m_descriptionEdit->setText(m_config.description);
    m_outputEdit->setText(m_config.output);
    m_outputDirEdit->setText(m_config.output_dir);
    m_sourceDirEdit->setText(m_config.source_dir);
    
    // 重新连接配置变化信号
    m_nameEdit->blockSignals(false);
    m_versionEdit->blockSignals(false);
    m_descriptionEdit->blockSignals(false);
    m_outputEdit->blockSignals(false);
    m_outputDirEdit->blockSignals(false);
    m_sourceDirEdit->blockSignals(false);
    
    // 验证路径
    validatePaths();
    
    // 更新文件列表
    m_filesList->clear();
    for (const QString& file : m_config.files) {
        m_filesList->addItem(file);
    }
    
    // 更新文件夹列表
    m_foldersList->clear();
    for (const QString& folder : m_config.folders) {
        m_foldersList->addItem(folder);
    }
    
    updateWindowTitle();
}

void MainWindow::clearUI()
{
    m_nameEdit->clear();
    m_versionEdit->clear();
    m_descriptionEdit->clear();
    m_outputEdit->clear();
    m_outputDirEdit->clear();
    m_sourceDirEdit->clear();
    m_filesList->clear();
    m_foldersList->clear();
}

void MainWindow::showProgress(const QString& message)
{
    m_progressBar->setVisible(true);
    m_progressBar->setRange(0, 100); // 确定进度范围
    m_progressBar->setValue(0);
    m_progressBar->setTextVisible(true); // 显示进度文本
    m_statusLabel->setText(message);
    statusBar()->showMessage(message);
    m_packBtn->setEnabled(false);
}

void MainWindow::hideProgress()
{
    m_progressBar->setVisible(false);
    m_statusLabel->setText("就绪");
    statusBar()->showMessage("就绪");
    m_packBtn->setEnabled(true);
}

void MainWindow::newConfig()
{
    m_config = PackConfig(); // 使用默认构造函数
    m_currentConfigPath.clear();
    m_configModified = false;
    updateUI();
}

void MainWindow::openConfig()
{
    QString filePath = QFileDialog::getOpenFileName(this, 
        "打开配置文件", 
        m_lastOpenDir,
        "JSON文件 (*.json)");
    
    if (!filePath.isEmpty()) {
        // 更新上次打开的目录
        m_lastOpenDir = QFileInfo(filePath).absoluteDir().absolutePath();
        
        if (m_config.loadFromFile(filePath)) {
            m_currentConfigPath = filePath;
            m_configModified = false;
            updateUI();
            statusBar()->showMessage("配置文件加载成功: " + QFileInfo(filePath).fileName());
        } else {
            QMessageBox::warning(this, "错误", "无法加载配置文件");
        }
    }
}

void MainWindow::saveConfig()
{
    if (m_currentConfigPath.isEmpty()) {
        saveAsConfig();
        return;
    }
    
    if (m_config.saveToFile(m_currentConfigPath)) {
        m_configModified = false;
        updateWindowTitle();
        statusBar()->showMessage("配置文件保存成功");
    } else {
        QMessageBox::warning(this, "错误", "无法保存配置文件");
    }
}

void MainWindow::saveAsConfig()
{
    QString filePath = QFileDialog::getSaveFileName(this,
        "保存配置文件",
        m_lastOpenDir,
        "JSON文件 (*.json)");
    
    if (!filePath.isEmpty()) {
        // 更新上次打开的目录
        m_lastOpenDir = QFileInfo(filePath).absoluteDir().absolutePath();
        
        if (m_config.saveToFile(filePath)) {
            m_currentConfigPath = filePath;
            m_configModified = false;
            updateWindowTitle();
            statusBar()->showMessage("配置文件保存成功: " + QFileInfo(filePath).fileName());
        } else {
            QMessageBox::warning(this, "错误", "无法保存配置文件");
        }
    }
}

void MainWindow::updateConfigFromUI()
{
    m_config.name = m_nameEdit->text();
    m_config.version = m_versionEdit->text();
    m_config.description = m_descriptionEdit->text();
    m_config.output = m_outputEdit->text();
    m_config.output_dir = m_outputDirEdit->text();
    m_config.source_dir = m_sourceDirEdit->text();
    
    // 更新文件列表
    m_config.files.clear();
    for (int i = 0; i < m_filesList->count(); ++i) {
        m_config.files.append(m_filesList->item(i)->text());
    }
    
    // 更新文件夹列表
    m_config.folders.clear();
    for (int i = 0; i < m_foldersList->count(); ++i) {
        m_config.folders.append(m_foldersList->item(i)->text());
    }
}

void MainWindow::addFiles()
{
    // 优先使用源目录，如果源目录无效则使用文档目录
    QString startDir;
    if (!m_config.source_dir.isEmpty() && QDir(m_config.source_dir).exists()) {
        startDir = m_config.source_dir;
    } else {
        startDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    }
    
    QStringList files = QFileDialog::getOpenFileNames(this,
        "选择要打包的文件",
        startDir);
    
    if (!files.isEmpty()) {
        for (const QString& file : files) {
            // 转换为相对路径
            QString relativePath = QDir(m_config.source_dir).relativeFilePath(file);
            if (!m_config.files.contains(relativePath)) {
                m_config.files.append(relativePath);
                m_filesList->addItem(relativePath);
            }
        }
        m_configModified = true;
        updateWindowTitle();
    }
}

void MainWindow::addFolders()
{
    // 优先使用源目录，如果源目录无效则使用文档目录
    QString startDir;
    if (!m_config.source_dir.isEmpty() && QDir(m_config.source_dir).exists()) {
        startDir = m_config.source_dir;
    } else {
        startDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    }
    
    QString folder = QFileDialog::getExistingDirectory(this,
        "选择要打包的文件夹",
        startDir);
    
    if (!folder.isEmpty()) {
        // 转换为相对路径
        QString relativePath = QDir(m_config.source_dir).relativeFilePath(folder);
        if (!m_config.folders.contains(relativePath)) {
            m_config.folders.append(relativePath);
            m_foldersList->addItem(relativePath);
            m_configModified = true;
            updateWindowTitle();
        }
    }
}

void MainWindow::removeSelectedItems()
{
    // 删除选中的文件
    QList<QListWidgetItem*> selectedFiles = m_filesList->selectedItems();
    for (QListWidgetItem* item : selectedFiles) {
        int row = m_filesList->row(item);
        m_config.files.removeAt(row);
        delete m_filesList->takeItem(row);
    }
    
    // 删除选中的文件夹
    QList<QListWidgetItem*> selectedFolders = m_foldersList->selectedItems();
    for (QListWidgetItem* item : selectedFolders) {
        int row = m_foldersList->row(item);
        m_config.folders.removeAt(row);
        delete m_foldersList->takeItem(row);
    }
    
    if (!selectedFiles.isEmpty() || !selectedFolders.isEmpty()) {
        m_configModified = true;
        updateUI();
    }
}

void MainWindow::startPacking()
{
    // 验证配置（不需要更新，因为已经实时更新了）
    if (!m_config.isValid()) {
        QMessageBox::warning(this, "配置错误", "请检查配置信息是否完整和正确");
        return;
    }
    
    // 如果有正在运行的任务，先清理
    if (m_workerThread && m_workerThread->isRunning()) {
        return; // 防止重复启动
    }
    
    // 创建新的工作线程和PackWorker
    m_workerThread = new QThread(this);
    m_packWorker = new PackWorker();
    
    // 设置配置到PackWorker
    m_packWorker->setConfig(m_config);
    
    // 将PackWorker移到工作线程
    m_packWorker->moveToThread(m_workerThread);
    
    // 连接信号
    connect(m_packWorker, &PackWorker::progressChanged, this, &MainWindow::onProgressChanged);
    connect(m_packWorker, &PackWorker::statusChanged, this, &MainWindow::onStatusChanged);
    connect(m_packWorker, &PackWorker::errorOccurred, this, &MainWindow::onErrorOccurred);
    connect(m_packWorker, &PackWorker::packingFinished, this, &MainWindow::onPackingFinished);
    
    // 连接线程控制信号
    connect(m_workerThread, &QThread::started, m_packWorker, &PackWorker::doPackFiles);
    connect(m_packWorker, &PackWorker::packingFinished, m_workerThread, &QThread::quit);
    connect(m_workerThread, &QThread::finished, m_packWorker, &PackWorker::deleteLater);
    connect(m_workerThread, &QThread::finished, m_workerThread, &QThread::deleteLater);
    
    // 清理指针当线程结束时
    connect(m_workerThread, &QThread::finished, [this]() {
        m_packWorker = nullptr;
        m_workerThread = nullptr;
    });
    
    // 禁用打包按钮，防止重复点击
    m_packBtn->setEnabled(false);
    
    // 显示进度
    showProgress("正在准备打包...");
    
    // 启动工作线程
    m_workerThread->start();
}

// PackWorker 信号处理方法
void MainWindow::onProgressChanged(int progress)
{
    qDebug() << "进度更新:" << progress << "%";
    if (m_progressBar) {
        m_progressBar->setValue(progress);
        // 强制刷新界面
        m_progressBar->repaint();
        QApplication::processEvents();
    }
}

void MainWindow::onStatusChanged(const QString& status)
{
    if (m_statusLabel) {
        m_statusLabel->setText(status);
    }
    if (statusBar()) {
        statusBar()->showMessage(status);
    }
    qDebug() << status;
}

void MainWindow::onErrorOccurred(const QString& error)
{
    qDebug() << "打包错误:" << error;
    hideProgress();
    m_packBtn->setEnabled(true);
    QMessageBox::warning(this, "打包错误", error);
}

void MainWindow::onPackingFinished(bool success, const QString& outputPath)
{
    hideProgress();
    m_packBtn->setEnabled(true);
    
    if (success) {
        QMessageBox::information(this, "成功", QString("文件打包完成!\n输出文件: %1").arg(outputPath));
        statusBar()->showMessage("打包完成");
    } else {
        QMessageBox::warning(this, "错误", "打包过程中发生错误");
        statusBar()->showMessage("打包失败");
    }
}

void MainWindow::onConfigChanged()
{
    // 实时更新配置对象
    updateConfigFromUI();
    
    m_configModified = true;
    // 只更新窗口标题，不重新设置所有UI内容
    updateWindowTitle();
}

void MainWindow::loadSettings()
{
    QSettings settings("PackTools", "FilePackTool");
    
    // 加载上次打开的目录
    m_lastOpenDir = settings.value("lastOpenDir", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).toString();
    
    // 加载窗口几何信息
    restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
    
    // 加载分割器状态
    if (m_mainSplitter) {
        m_mainSplitter->restoreState(settings.value("splitterState").toByteArray());
    }
}

void MainWindow::saveSettings()
{
    QSettings settings("PackTools", "FilePackTool");
    
    // 保存上次打开的目录
    settings.setValue("lastOpenDir", m_lastOpenDir);
    
    // 保存窗口几何信息
    settings.setValue("geometry", saveGeometry());
    settings.setValue("windowState", saveState());
    
    // 保存分割器状态
    if (m_mainSplitter) {
        settings.setValue("splitterState", m_mainSplitter->saveState());
    }
}

void MainWindow::updateWindowTitle()
{
    QString title = "Pack Tools - 文件打包工具";
    if (!m_currentConfigPath.isEmpty()) {
        title += " - " + QFileInfo(m_currentConfigPath).fileName();
    }
    if (m_configModified) {
        title += " *";
    }
    setWindowTitle(title);
}

void MainWindow::selectOutputDir()
{
    QString currentDir = m_outputDirEdit->text().isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) : m_outputDirEdit->text();
    
    QString dir = QFileDialog::getExistingDirectory(this,
        "选择输出目录",
        currentDir);
    
    if (!dir.isEmpty()) {
        m_outputDirEdit->setText(dir);
        validatePaths();
    }
}

void MainWindow::selectSourceDir()
{
    QString currentDir = m_sourceDirEdit->text().isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) : m_sourceDirEdit->text();
    
    QString dir = QFileDialog::getExistingDirectory(this,
        "选择源目录",
        currentDir);
    
    if (!dir.isEmpty()) {
        m_sourceDirEdit->setText(dir);
        validatePaths();
    }
}

void MainWindow::validatePaths()
{
    // 验证输出目录
    QString outputDir = m_outputDirEdit->text();
    if (!outputDir.isEmpty() && !QDir(outputDir).exists()) {
        m_outputDirEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        m_outputDirEdit->setStyleSheet("");
    }
    
    // 验证源目录
    QString sourceDir = m_sourceDirEdit->text();
    if (!sourceDir.isEmpty() && !QDir(sourceDir).exists()) {
        m_sourceDirEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        m_sourceDirEdit->setStyleSheet("");
    }
}
